import queue
import threading
from concurrent.futures import ThreadPoolExecutor
from typing import Callable, Any
import atexit
from ..utils.log import get_logger

logger = get_logger(__name__) 

# 全局配置
MAX_WORKERS = 5

# 任务队列（线程安全）
_task_queue = queue.Queue()

# 线程池执行器
_executor = ThreadPoolExecutor(max_workers=MAX_WORKERS)

# 后台消费者线程
_worker_thread = None
_running = False

def _worker():
    """后台持续消费任务的线程"""
    global _running
    while _running:
        item = None
        try:
            # 阻塞获取任务，超时是为了能响应停止信号
            item = _task_queue.get(timeout=1)
            if item is None:  # 停止信号
                break

            func, args, kwargs = item
            # 提交到线程池执行（不阻塞消费线程）
            future = _executor.submit(func, *args, **kwargs)
            # 可选：添加回调打印结果或错误
            # future.add_done_callback(
            #     lambda fut: logger.info(f"[Task Result] {fut.result() if not fut.exception() else 'Error: ' + str(fut.exception())}")
            # )
        except queue.Empty:
            continue
        except Exception as e:
            logger.info(f"[Worker Error] {e}")
            if item is not None:  # 只有获取到项目时才调用
                _task_queue.task_done()

def start_queue():
    """启动任务队列系统"""
    global _worker_thread, _running
    if _running:
        return
    _running = True
    _worker_thread = threading.Thread(target=_worker, daemon=True)
    _worker_thread.start()
    logger.info(f"✅ Task queue started with {MAX_WORKERS} workers.")

def stop_queue():
    """优雅关闭任务队列"""
    global _running
    if not _running:
        return
    _running = False
    _task_queue.put(None)  # 发送停止信号
    if _worker_thread:
        _worker_thread.join(timeout=5)
    _executor.shutdown(wait=True)
    logger.info("🛑 Task queue stopped.")

# 程序退出时自动关闭
atexit.register(stop_queue)

def enqueue_task(func: Callable, *args, **kwargs):
    """
    提交一个任务到队列
    func: 任意同步函数
    *args, **kwargs: 任意参数，支持复杂对象
    """
    if not _running:
        raise RuntimeError("Task queue not started. Call start_queue() first.")
    _task_queue.put((func, args, kwargs))
    logger.info(f"📥 Task enqueued: {func.__name__} with args={args}, kwargs={kwargs}")

def get_queue_size() -> int:
    """获取当前队列中等待的任务数"""
    return _task_queue.qsize()